import math

# 比较运算符优先级
def compare_operation(operate_one, operate_two, stack_type):
    if operate_one == ')' and operate_two == '(':
        return '<'
    if operate_two == '' or operate_two == '(':
        return '>'
    if stack_type == 'out':
        if '+' == operate_one:
            if '(' == operate_two:
                return '>'
            else:
                return '<'
        if '-' == operate_one:
            if '(' == operate_two:
                return '>'
            else:
                return '<'
        if '*' == operate_one:
            if operate_two == '+' or operate_two == '-'or operate_two == '=':
                return '>'
            else:
                return '<'
        if '/' == operate_one:
            if operate_two == '+' or operate_two == '-'or operate_two == '=':
                return '>'
            else:
                return '<'
        if '%' == operate_one:
            if operate_two == '+' or operate_two == '-' or operate_two == '=':
                return '>'
            else:
                return '<'
        if '^' == operate_one:
            if operate_two == '+' or operate_two == '-' or operate_two == '=' \
                    or operate_two == '*' or operate_two == '%' or operate_two == '/':
                return '>'
            else:
                return '<'
        if '&' == operate_one:
            if operate_two == '+' or operate_two == '-' or operate_two == '=' \
                    or operate_two == '*' or operate_two == '%' or operate_two == '/':
                return '>'
            else:
                return '<'
        if ')' == operate_one:
            if operate_two == '=':
                return '>'
            else:
                return '<'

# 计算数值结果
def compute_result(number_one, number_two, operate):
    if number_one == '':
        number_one = '0'
    if number_two == '':
        number_two == '0'
    param_one = float(number_one)
    param_two = float(number_two)
    if operate == '+':
        return param_two + param_one
    if operate == '-':
        return param_two - param_one
    if operate == '*':
        return param_two * param_one
    if operate == '/':
        if param_one == 0:
            return math.inf
        return param_two / param_one
    if operate == '%':
        return param_two % param_one
    if operate == '^':
        if param_two < 0:
            if param_one > 0 and param_one % 2 == 1:
                return param_two ** (1/param_one)
            elif param_one < 0 and param_one % 2 == 1:
                return 1/(param_two ** (1/param_one))
            else:
                return math.inf
        if param_two > 0:
            if param_one > 0:
                return param_two ** (1/param_one)
            elif param_one < 0:
                return 1/(param_two ** (1/param_one))
            else:
                return math.inf
    if operate == '&':
        return param_two ** param_one

# 文本预处理
def basic_work(input_str):
    # 适应输入空字符串
    if not len(input_str):
        input_str = 'error in statement, NULL string :'
        return input_str
    # 适应操作符连续输入
    for index in range(len(input_str)-1):
        if is_operator(input_str[index]) and is_operator(input_str[index+1]):
            input_str = 'error in statement, duplicate operator :'+str(input_str[index])
            return input_str
    # 适应首字符存在符号可能性
    if input_str[0] == '-':
        input_str = '0'+input_str
    # 适应首字符不得为其他字符
    if is_operator(input_str[0]):
        if input_str[0] == '-':
            pass
        else:
            input_str = 'error in statement,first can not be operator:'+ input_str[0]
            return input_str
    length = len(input_str)
    # 适应用户不输入等号
    if input_str[length-1] == '=':
        input_str = input_str[0:length-1]
        input_str += '+0='
    else:
        input_str += '+0='
    # 适应括号非对称输入
    if input_str.count('(') != input_str.count(')'):
        input_str = 'error in brackets！ it was off-balance'
    return input_str
# 非法字符检测器
def not_operate(character):
    if character != '+' and character != '-' and character != '*' and character != '/' and character != '^' \
            and character != '(' and character != ')' and character != '&' and character != '=' \
            and character != '%' and character != '.' and character !=' ':
        return True
    else:
        return False

# 出栈，压栈运算
def simple_caculate(operate_type, top, temp, input_index, operate=[], operator=[]):
    if compare_operation(operate_type, top, temp) == '>':
        operate.append(input_index)
    if compare_operation(operate_type, top, temp) == '<':
        operator.append(compute_result(operator.pop(), operator.pop(), operate.pop()))
        operate.append(input_index)

# 临时字符运算
def set_operator_value(temp_str, operator=[]):
    if temp_str == '':
        pass
    else:
        if temp_str.count('.') > 1:
            operator.append(str(math.inf))
        else:
            operator.append(temp_str)
        temp_str = ''
    return True,temp_str
# 是否为数字判断
def is_operator(character):
    if character == '+' or character == '-' or character == '*' or character == '/' or character == '^' \
            or character == '&' or character == '='or character == '%' or character == '.':
        return True
    else:
        return False